package net.lijingye.education.service.impl;

import net.lijingye.education.dao.*;
import net.lijingye.education.entity.*;
import net.lijingye.education.exception.*;
import net.lijingye.education.service.UtilService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.method.P;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * Created by LijingYe on 2016/3/29.
 */
@Service
@Transactional
public class UtilServiceImpl implements UtilService {
    @Autowired
    private TermDao termDao;
    @Autowired
    private ProvinceDao provinceDao;
    @Autowired
    private CityDao cityDao;
    @Autowired
    private PPTDao pptDao;
    @Autowired
    private SourceDao sourceDao;
    @Autowired
    private SourceReplyDao sourceReplyDao;
    @Autowired
    private TopicDao topicDao;
    @Autowired
    private TopicReplyDao topicReplyDao;
    @Autowired
    private TweetDao tweetDao;
    @Autowired
    private TweetReplyDao tweetReplyDao;
    @Autowired
    private AssignmentDao assignmentDao;


    public List<Term> getTermList() throws DaoException {
        return termDao.findByQuery("ORDER BY termId DESC");
    }

    public List<Province> getProvinceList() throws DaoException {
        return provinceDao.findAll();
    }

    @Override
    public Province getProvinceById(String provinceId) throws DaoException, ProfileProvinceNotExistsException {
        Province province = provinceDao.getById(provinceId);
        if (null == province) {
            throw new ProfileProvinceNotExistsException("Province `" + provinceId + "`");
        }
        return province;
    }

    public List<City> getCityListByProvinceId(Serializable provinceId) throws ObjectNotExistsException, DaoException {
        List<City> cityList = provinceDao.getById(provinceId).getCityList();
        if (cityList.isEmpty()) {
            throw new ObjectNotExistsException("Province `" + provinceId + "`");
        }
        return cityList;
    }

    @Override
    public City getCityById(String cityId) throws DaoException, ProfileCityNotExistsException {
        City city = cityDao.getById(cityId);
        if (null == city) {
            throw new ProfileCityNotExistsException("City `" + cityId + "`");
        }
        return city;
    }

    @Override
    public PPT getPPTById(String pptId) throws DaoException, ObjectNotExistsException {
        try {
            Integer realPPTId = Integer.valueOf(pptId);
            PPT ppt = pptDao.getById(realPPTId);
            if (null == ppt) {
                throw new ObjectNotExistsException("PPT `" + pptId + "`");
            }
            return ppt;
        } catch (NumberFormatException e) {
            throw new ObjectNotExistsException("PPT `" + pptId + "`");
        }
    }

    @Override
    public PPT getPPTByIdAndDownload(String pptId) throws DaoException, ObjectNotExistsException {
        PPT ppt = this.getPPTById(pptId);
        ppt.setDownloadTime(ppt.getDownloadTime() + 1);
        pptDao.update(ppt);
        return ppt;
    }

    @Override
    public Topic getTopicById(String topicId) throws DaoException, ObjectNotExistsException {
        try {
            Integer realTopicId = Integer.valueOf(topicId);
            Topic topic = topicDao.getById(realTopicId);
            if (null == topic) {
                throw new ObjectNotExistsException("Topic `" + topicId + "`");
            }
            return topic;
        } catch (NumberFormatException e) {
            throw new ObjectNotExistsException("Topic `" + topicId + "`");
        }
    }

    @Override
    public Topic getTopicByIdAndKick(String topicId) throws DaoException, ObjectNotExistsException {
        Topic topic = this.getTopicById(topicId);
        topic.setKickTime(topic.getKickTime() + 1);
        topicDao.update(topic);
        return topic;
    }

    @Override
    public TopicReply addTopicReply(String topicId, Date time, String content, User user, User toUser) throws DaoException, ObjectNotExistsException {
        Topic topic = this.getTopicById(topicId);
        List<TopicReply> topicReplyList = topic.getTopicReplyList();
        TopicReply topicReply = new TopicReply(time, content, topic, user, toUser, new ArrayList<>());
        topicReplyList.add(topicReply);
        topicDao.update(topic);
        return topicReply;
    }

    @Override
    public TopicReply addTopicReplyFile(Integer topicReplyId, List<String> fileList) throws DaoException, ObjectNotExistsException {
        TopicReply topicReply = topicReplyDao.getById(topicReplyId);
        if (null == topicReply) {
            throw new ObjectNotExistsException("TopicReply `" + topicReplyId + "`");
        }
        List<TopicReplyFile> topicReplyFileList = topicReply.getTopicReplyFileList();
        fileList.forEach(file -> {
            TopicReplyFile topicReplyFile = new TopicReplyFile(topicReply.getId(), file);
            topicReplyFileList.add(topicReplyFile);
        });
        topicReplyDao.update(topicReply);
        return topicReply;
    }

    public Source getSourceById(String sourceId) throws DaoException, ObjectNotExistsException {
        try {
            Integer realSourceId = Integer.valueOf(sourceId);
            Source source = sourceDao.getById(realSourceId);
            if (null == source) {
                throw new ObjectNotExistsException("Source `" + sourceId + "`");
            }
            return source;
        } catch (NumberFormatException e) {
            throw new ObjectNotExistsException("Source `" + sourceId + "`");
        }
    }

    public Source getSourceByIdAndKick(String sourceId) throws DaoException, ObjectNotExistsException {
        Source source = this.getSourceById(sourceId);
        source.setKickTime(source.getKickTime() + 1);
        sourceDao.update(source);
        return source;
    }

    public Source getSourceByIdAndDownload(String sourceId) throws DaoException, ObjectNotExistsException {
        Source source = this.getSourceById(sourceId);
        source.setDownloadTime(source.getDownloadTime() + 1);
        sourceDao.update(source);
        return source;
    }

    public SourceReply addSourceReply(String sourceId, Date time, String content, User user) throws DaoException, ObjectNotExistsException {
        Source source = this.getSourceById(sourceId);
        List<SourceReply> sourceReplyList = source.getSourceReplyList();
        SourceReply sourceReply = new SourceReply(time, content, source, user, new ArrayList<>());
        sourceReplyList.add(sourceReply);
        sourceDao.update(source);
        return sourceReply;
    }

    public SourceReply addSourceReplyFile(Integer sourceReplyId, List<String> fileList) throws DaoException, ObjectNotExistsException {
        SourceReply sourceReply = sourceReplyDao.getById(sourceReplyId);
        if (null == sourceReply) {
            throw new ObjectNotExistsException("SourceReply `" + sourceReplyId + "`");
        }
        List<SourceReplyFile> sourceReplyFileList = sourceReply.getSourceReplyFileList();
        fileList.forEach(file -> {
            SourceReplyFile sourceReplyFile = new SourceReplyFile(sourceReply.getId(), file);
            sourceReplyFileList.add(sourceReplyFile);
        });
        sourceReplyDao.update(sourceReply);
        return sourceReply;
    }

    public String getSourceAvgScore(String sourceId) throws DaoException, ObjectNotExistsException {
        Source source = this.getSourceById(sourceId);
        List<SourceScore> sourceScoreList = source.getSourceScoreList();
        int total = 0;
        for (int i = 0; i < sourceScoreList.size(); i++) {
            total += sourceScoreList.get(i).getScore();
        }
        DecimalFormat decimalFormat = new DecimalFormat("#.0");
        double score = (double) total / sourceScoreList.size();
        return decimalFormat.format(score);
    }

    public SourceScore getSourceMyScore(String sourceId, User user) throws DaoException, ObjectNotExistsException {
        Source source = this.getSourceById(sourceId);
        List<SourceScore> sourceScoreList = source.getSourceScoreList();
        Iterator<SourceScore> iterator = sourceScoreList.iterator();
        while (iterator.hasNext()) {
            SourceScore sourceScore = iterator.next();
            if (sourceScore.getUser().getId().equals(user.getId())) {
                return sourceScore;
            }
        }
        return null;
    }

    public String addSourceScore(String sourceId, User user, int score) throws DaoException, ObjectNotExistsException {
        Source source = this.getSourceById(sourceId);
        List<SourceScore> sourceScoreList = source.getSourceScoreList();
        SourceScore sourceScore = this.getSourceMyScore(sourceId, user);
        if (null == sourceScore) {
            sourceScoreList.add(new SourceScore(source, user, score));
        } else {
            sourceScore.setScore(score);
        }
        sourceDao.update(source);
        return this.getSourceAvgScore(sourceId);
    }

    public Tweet getTweetById(String tweetId) throws DaoException, ObjectNotExistsException {
        Tweet tweet = tweetDao.getById(tweetId);
        if (null == tweet) {
            throw new ObjectNotExistsException("Tweet `" + tweetId + "`");
        }
        return tweet;
    }

    public TweetReply addTweetReply(String tweetId, Date time, String content, User user, User toUser) throws DaoException, ObjectNotExistsException {
        Tweet tweet = tweetDao.getById(tweetId);
        if (null == tweet) {
            throw new ObjectNotExistsException("Tweet `" + tweetId + "`");
        }
        List<TweetReply> tweetReplyList = tweet.getTweetReplyList();
        TweetReply tweetReply = new TweetReply(tweet, user, toUser, content, time, new ArrayList<>());
        tweetReplyList.add(tweetReply);
        tweetDao.update(tweet);
        return tweetReply;
    }

    public TweetReply addTweetReplyFile(String tweetReplyId, List<String> fileList) throws DaoException, ObjectNotExistsException {
        TweetReply tweetReply = tweetReplyDao.getById(tweetReplyId);
        if (null == tweetReply) {
            throw new ObjectNotExistsException("TweetReply `" + tweetReplyId + "`");
        }
        List<TweetReplyFile> tweetReplyFileList = tweetReply.getTweetReplyFileList();
        fileList.forEach(file -> {
            TweetReplyFile tweetReplyFile = new TweetReplyFile(tweetReply.getId(), file);
            tweetReplyFileList.add(tweetReplyFile);
        });
        tweetReplyDao.update(tweetReply);
        return tweetReply;
    }

    @Override
    public Assignment getAssignmentById(String assignmentId) throws DaoException, ObjectNotExistsException {
        Assignment assignment = assignmentDao.getById(assignmentId);
        if (null == assignment) {
            throw new ObjectNotExistsException("Assignment `" + assignmentId + "`");
        }
        return assignment;
    }

    @Override
    public Assignment getAssignmentByIdAndDownloadAnswer(String assignmentId) throws DaoException, ObjectNotExistsException, FileNotFoundException {
        Assignment assignment = this.getAssignmentById(assignmentId);
        if (null == assignment.getAnswer()) {
            throw new FileNotFoundException("Assignment Answer `" + assignmentId + "`");
        }
        //写日志
        return assignment;
    }

    @Override
    public StudentAssignment getStudentAssignmentById(String assignmentId, String userId) throws DaoException, ObjectNotExistsException {
        Assignment assignment = this.getAssignmentById(assignmentId);
        List<StudentAssignment> studentAssignmentList = assignment.getStudentAssignmentList();
        for (StudentAssignment studentAssignment : studentAssignmentList) {
            if (userId.equals(studentAssignment.getUser().getId())) {
                return studentAssignment;
            }
        }
        ;
        return null;
    }

    @Override
    public StudentAssignment getStudentAssignmentByIdAndDownload(String assignmentId, String userId) throws DaoException, ObjectNotExistsException, FileNotFoundException {
        StudentAssignment studentAssignment = this.getStudentAssignmentById(assignmentId, userId);
        if (null == studentAssignment) {
            throw new FileNotFoundException("Assignment My Answer `" + assignmentId + "`");
        }
        return studentAssignment;
    }
}
